package br.com.ss.portal.model.dao;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.Criterion;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public abstract class HibernateDAOGeneric<T> extends HibernateDaoSupport
		implements IGenericDAO<T> {

	private Class<T> persistentClass;

	public static Log LOG = LogFactory.getLog(HibernateDAOGeneric.class);

	@SuppressWarnings(value = "unchecked")
	public HibernateDAOGeneric() {
		this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
	}

	public Class<T> getPersistentClass() {
		return persistentClass;
	}

	@Override
	public T save(T entity) throws HibernateException {
		try {

			this.getHibernateTemplate().flush();
			this.getHibernateTemplate().clear();
			this.getHibernateTemplate().saveOrUpdate(entity);
			return entity;
		} catch (final HibernateException ex) {
			HibernateDAOGeneric.LOG.error(ex);
			throw convertHibernateAccessException(ex);
		}
	}

	@Override
	public void delete(T entity) {
		try {
			this.getHibernateTemplate().delete(entity);
		} catch (final HibernateException ex) {
			HibernateDAOGeneric.LOG.error(ex);
			throw convertHibernateAccessException(ex);
		}
	}

	@Override
	public List<T> getALL() {
		try {
			return this.getHibernateTemplate().loadAll(getPersistentClass());
		} catch (final HibernateException ex) {
			HibernateDAOGeneric.LOG.error(ex);
			throw convertHibernateAccessException(ex);
		}
	}

	@SuppressWarnings(value = "unchecked")
	public List<T> getByCriterion(Criterion... filters) {
		try {
			Criteria body = this.getHibernateTemplate().getSessionFactory()
					.getCurrentSession().createCriteria(getPersistentClass());
			for (Criterion filter : filters) {
				body.add(filter);
			}
			return body.list();
		} catch (final HibernateException ex) {
			HibernateDAOGeneric.LOG.error(ex);
			throw convertHibernateAccessException(ex);
		}
	}

}
